﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Entities</title>
<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
<style type="text/css">
.auto-style1 {
	background-color: #F5F5F5;
}
</style>
</head>

<body>

<ul>
	<li><a href="#DocAppLangs">Application languages</a></li>
	<li><a href="#DocLocalizationSources">Localization sources</a><ul>
		<li><a href="#DocLocalizeXml">XML files</a></li>
		<li><a href="#DocLocalizeResources">Resource files</a></li>
		<li><a href="#DocLocalizeCustom">Custom sources</a></li>
	</ul>
	</li>
	<li><a href="#DocGetText">Getting a localized text</a><ul>
		<li><a href="#DocInServer">In server-side code</a></li>
		<li><a href="#DocInControllers">In MVC controllers</a></li>
		<li><a href="#DocInViews">In MVC views</a></li>
		<li><a href="#DocInJavascript">In Javascript</a></li>
	</ul>
	</li>
	<li><a href="#DocExtending">Extending localization sources</a></li>
	<li><a href="#DocConclusion">Conclusion</a></li>
</ul>

<h3 id="DocAppLangs">Application languages</h3>
<p>An application has at least one language for user interface. Many 
applications have more than one language. ASP.NET Boilerplate provides a 
flexible localization system for an application.</p>
<p>The first thing is to declare which languages are supported. This is done
<strong>PreInitialize</strong> event of your
<a href="/Pages/Documents/Module-System">module</a> as shown below:</p>
<pre lang="cs">Configuration.Localization.Languages.Add(new LanguageInfo(&quot;en&quot;, &quot;English&quot;, &quot;famfamfam-flag-england&quot;, true));
Configuration.Localization.Languages.Add(new LanguageInfo(&quot;tr&quot;, &quot;T&#252;rk&#231;e&quot;, &quot;famfamfam-flag-tr&quot;));</pre>
<p>In server side, you can <a href="/Pages/Documents/Dependency-Injection">
inject</a> and use <strong>ILocalizationManager</strong>. In client side, you 
can use <strong>abp.localization</strong> javascript API to get list of 
all available languages and the current language. famfamfam-flag-england (and 
tr) is just a CSS class, you can change it upon your needs. Then you can use it 
on UI to show related flag.</p>
<p>ASP.NET Boilerplate <a href="/Templates">templates</a> uses this system to 
show a <strong>language-switch</strong> combobox to the user. Try to create a 
template and see source codes for more.</p>

<h3 id="DocLocalizationSources">Localization sources</h3>
<p>Localization 
texts can be stored in different sources. 
Even you can use more than one source in same application (If you have more than 
one <a href="/Pages/Documents/Module-System">module</a>, each module can define 
a seperated localization source).<strong> 
ILocalizationSource</strong> interface should be implemented for a localization 
source. Then it is <strong>register</strong>ed to ASP.NET Boilerplate's 
localization configuration. </p>
<p>Each localization source must have a <strong>unique source name</strong>. 
There are pre-defined localization source types to use <strong>XML 
files</strong> and <strong>resource</strong> files.</p>

<h4 id="DocLocalizeXml">XML files</h4>
<p>Localization texts can be stored in XML files. Content of an XML file is 
something like that:</p>
<pre lang="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;localizationDictionary <strong>culture=&quot;en&quot;</strong>&gt;
  &lt;texts&gt;
    &lt;text name=&quot;TaskSystem&quot; value=&quot;Task System&quot; /&gt;
    &lt;text name=&quot;TaskList&quot; value=&quot;Task List&quot; /&gt;
    &lt;text name=&quot;NewTask&quot; value=&quot;New Task&quot; /&gt;
    &lt;text name=&quot;Xtasks&quot; value=&quot;{0} tasks&quot; /&gt;
    &lt;text name=&quot;CompletedTasks&quot; value=&quot;Completed tasks&quot; /&gt;
    &lt;text name=&quot;EmailWelcomeMessage&quot;&gt;Hi,
Welcome to Simple Task System! This is a sample
email content.&lt;/text&gt;
  &lt;/texts&gt;
&lt;/localizationDictionary&gt;</pre>
<p>XML file must be unicode (<strong>utf-8</strong>). <strong>culture="en"</strong> declares that this XML file 
contains English texts. For text nodes; <strong>name</strong> attribute is 
used to identify a text. You can use <strong>value </strong>attribute or 
<strong>inner text </strong>(like the 
last one) to set value of the localization text. We create a seperated XML file for 
<strong>each language</strong> as shown below:</p>
<p>
<img alt="Localization files" height="89" src="/SiteFiles/Content/Documents/Resources/localization_files2.png" width="217" /></p>
<p><strong>SimpleTaskSystem</strong> is the <strong>source name</strong> here 
and SimpleTaskSystem.xml defines the <strong>default language</strong>. When a text is requested, ASP.NET 
Boilerplate gets the text from current language's XML file (finds current 
language using 
Thread.CurrentThread.<strong>CurrentUICulture</strong>). If it does not exists 
in the current language, it gets the text from default language's XML file.</p>
<h5>Registering XML localization sources</h5>
<p>XML files can be stored in <strong>file system</strong> or can be <strong>
embedded</strong> into an assembly.</p>
<p>For <strong>file system</strong> stored XMLs, we can register an XML 
localization source as shown below:</p>
<pre lang="cs">Configuration.Localization.Sources.Add(
    new DictionaryBasedLocalizationSource(
        &quot;SimpleTaskSystem&quot;,
        new <strong>XmlFileLocalizationDictionaryProvider</strong>(
            HttpContext.Current.Server.MapPath(&quot;~/Localization/SimpleTaskSystem&quot;)
            )
        )
    );</pre>
<p>This is done in <strong>PreInitialize</strong> event of a module (See
<a href="/Pages/Documents/Module-System">module system</a> for more info). 
ASP.NET Boilerplate finds all XML files in given directory and registers the 
localization source.</p>
<p>For <strong>embedded XML files</strong>, we should mark all 
localization XML files as embedded resource (Select XML files, open properties 
window (F4) and change Build Action as Embedded Resource). Then we can register 
the localization source as shown below:</p>
<pre lang="cs">Configuration.Localization.Sources.Add(
    new DictionaryBasedLocalizationSource(
        &quot;SimpleTaskSystem&quot;,
        new <strong>XmlEmbeddedFileLocalizationDictionaryProvider</strong>(
            Assembly.GetExecutingAssembly(),
            &quot;MyCompany.MyProject.Localization.Sources&quot;
            )
        )
    );</pre>
<p><strong>XmlEmbeddedFileLocalizationDictionaryProvider</strong> gets an 
assembly containing XML files (GetExecutingAssembly simply refers to current 
assembly) and a <strong>namespace</strong> of XML files (namespace is calculated 
assembly name + folder hierarchy of XML files). </p>
<p>Note that: When adding language postfix to embedded XML files, don't use dot 
notation like 'MySource.tr.xml', instead use dash like '<strong>MySource-tr.xml</strong>' 
since dot notation causes problems when finding resources.</p>
<h4 id="DocLocalizeResources">Resource files</h4>
<p>Localization text can also be stored in .NET's resource files. We can create 
a resource file for each language as shown below (Right click to the project, 
choose add new item then find resources file).</p>
<p>
<img alt="Localization resource files" height="97" src="/SiteFiles/Content/Documents/Resources/resource_files.png" width="149" /></p>
<p><strong>MyTexts.resx</strong> contains the default language texts and MyTexts<strong>.tr</strong>.resx 
contains texts for Turkish language. When we open MyTexts.resx, we can see all 
texts:</p>
<p>
<img alt="Content of a resource file" height="174" src="/SiteFiles/Content/Documents/Resources/resource_files_content.png" width="466" /></p>
<p>In this case, ASP.NET Boilerplate uses .NET's built-in resource manager for 
localization. You should configure a localization source for the resource:</p>
<pre lang="cs">Configuration.Localization.Sources.Add(
    new ResourceFileLocalizationSource(
        &quot;MySource&quot;,
        MyTexts.ResourceManager
        ));</pre>
<p><strong>Uniqe name</strong> of the source is <strong>MySource</strong> here. And 
<strong>MyTexts.ResourceManager</strong> is a 
reference to the resource manager to be used to get localized texts.&nbsp;This is done in <strong>Initialize</strong> event of the module (See
<a href="/Pages/Documents/Module-System">module system</a> for more info).</p>
<h4 id="DocLocalizeCustom">Custom source</h4>
<p>A custom localization source can be implemented to store texts in different 
sources such as in a database. You can directly implement the <strong>
ILocalization</strong> interface or you can derive from <strong>
DictionaryBasedLocalizationSource</strong> 
class to make implementation easier.</p>
<h3 id="DocGetText">Getting a localized text</h3>
<p>After creating a source and register it to the ASP.NET Boilerplate's 
localization system, texts can be localized easily.</p>
<h4 id="DocInServer">In server side</h4>
<p>In server side, we can inject <strong>ILocalizationManager</strong> and use 
it's <strong>GetString</strong> method. If we can not inject it, we can simply call <strong>LocalizationHelper.GetString </strong>
with source name and text name:</p>
<pre lang="cs">var s1 = LocalizationHelper.GetString("SimpleTaskSystem", "NewTask");</pre>
<p>To do not repeat source name always, you can first <strong>get the source</strong>, 
then get a string from the source:</p>
<pre lang="cs">var source = LocalizationHelper.GetSource("SimpleTaskSystem");
var s<span lang="tr">1</span> = source.GetString("NewTask");</pre>
<p>This returns text in the current language. There are also overrides of 
GetString to get text in different languages and formatted by arguments.</p>
<p>Note that: Prefer injecting and using ILocalizationManager where possible 
since LocalizationHelper is static and statics are not well testable (for who 
writes unit tests).</p>
<p>If you need to localization in an
<a href="/Pages/Documents/Application-Services#DocAppServiceClass">application 
service</a>, in a controller or in a view, there are shortcut <strong>L</strong> 
methods.</p>
<h4 id="DocInControllers">In MVC controllers</h4>
<p>Localization texts are generally needed in MVC Controller and Views. There is 
a shortcut for that. See the sample controller below:</p>
<pre lang="cs">public class HomeController : SimpleTaskSystemControllerBase
{
    public ActionResult Index()
    {
        var helloWorldText = L("HelloWorld");
        return View();
    }
}</pre>
<p><strong>L</strong> method is used to localize a string. Surely, you must 
supply a source name. It's done in SimpleTaskSystemControllerBase as shown 
below:</p>
<pre lang="cs">public abstract class SimpleTaskSystemControllerBase : AbpController
{
    protected SimpleTaskSystemControllerBase()
    {
        LocalizationSourceName = "SimpleTaskSystem";
    }
}</pre>
<p>Notice that it is derived from <strong>AbpController</strong>. Thus, you can 
easily localize texts with <strong>L</strong> method. </p>
<h4 id="DocInViews">In MVC views</h4>
<p>Same <strong>L</strong> method also exists in 
views:</p>
<pre lang="cs">&lt;div&gt;
    &lt;form id=&quot;NewTaskForm&quot; role=&quot;form&quot;&gt;
        &lt;div class=&quot;form-group&quot;&gt;
            &lt;label for=&quot;TaskDescription&quot;&gt;<strong>@L(&quot;TaskDescription&quot;)</strong>&lt;/label&gt;
            &lt;textarea id=&quot;TaskDescription&quot; data-bind=&quot;value: task.description&quot; class=&quot;form-control&quot; rows=&quot;3&quot; placeholder=&quot;<strong>@L(&quot;EnterDescriptionHere&quot;)</strong>&quot; required&gt;&lt;/textarea&gt;
        &lt;/div&gt;
        &lt;div class=&quot;form-group&quot;&gt;
            &lt;label for=&quot;TaskAssignedPerson&quot;&gt;<strong>@L(&quot;AssignTo&quot;)</strong>&lt;/label&gt;
            &lt;select id=&quot;TaskAssignedPerson&quot; data-bind=&quot;options: people, optionsText: &#39;name&#39;, optionsValue: &#39;id&#39;, value: task.assignedPersonId, optionsCaption: &#39;<strong>@L(&quot;SelectPerson&quot;)</strong>&#39;&quot; class=&quot;form-control&quot;&gt;&lt;/select&gt;
        &lt;/div&gt;
        &lt;button data-bind=&quot;click: saveTask&quot; type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;<strong>@L(&quot;CreateTheTask&quot;)</strong>&lt;/button&gt;
    &lt;/form&gt;
&lt;/div&gt;</pre>
<p>To make this work, you should derive your views from a base class that sets 
the source name:</p>
<pre lang="cs">public abstract class SimpleTaskSystemWebViewPageBase : SimpleTaskSystemWebViewPageBase&lt;dynamic&gt;
{

}

public abstract class SimpleTaskSystemWebViewPageBase&lt;TModel&gt; : AbpWebViewPage&lt;TModel&gt;
{
    protected SimpleTaskSystemWebViewPageBase()
    {
        LocalizationSourceName = &quot;SimpleTaskSystem&quot;;
    }
}</pre>
<p>And set this view base class in web.config:</p>
<pre lang="cs">&lt;pages pageBaseType=&quot;SimpleTaskSystem.Web.Views.SimpleTaskSystemWebViewPageBase&quot;&gt;</pre>
<p>All these for controllers and views are ready when you create your solution 
from one of the ASP.NET Boilerplate <a href="/Templates">templates</a>.</p>

<h4 id="DocInJavascript">In javascript</h4>
<p>ASP.NET Boilerplate makes possible to use same localization texts in also 
javascript code. First, you should be added dynamic ABP scripts to the page:</p>
<pre lang="xml">&lt;script src=&quot;/Abp<span lang="tr">S<span class="auto-style1">cripts</span></span>/GetScripts&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</pre>
<p>ASP.NET Boilerplate automatically generates needed javascript code to get 
localized texts in the client side. Then you can easily get a localized text in 
javascript as shown below:</p>
<pre lang="js">var s1 = abp.localization.localize('NewTask', 'SimpleTaskSystem');</pre>
<p>NewTask is the text name and SimpleTaskSystem is the source name here. To do 
not repeat source name, you can first get the source then get the text:</p>
<pre lang="js">var source = abp.localization.getSource('SimpleTaskSystem');
var s<span lang="tr">1</span> = source('NewTask');</pre>
<p>Localization method can also get additional format arguments. Example:</p>
<pre lang="js">abp.localization.localize('RoleDeleteWarningMessage', 'MySource', 'Admin');

//shortcut if source is got using getSource as shown above
source('RoleDeleteWarningMessage', 'Admin');</pre>
<p>if RoleDeleteWarningMessage = 'Role {0} will be deleted', then localized text 
will be 'Role Admin will be deleted'.</p>

<h3 id="DocExtending">Extending localization sources</h3>
<p>Assume that we use a module which defines it's own localization source. We 
may need to change it's localized texts, add new texts or translate to other languages. 
ASP.NET Boilerplate allows extending a localization source. It currently works 
for XML files (Actually any localization source implements 
IDictionaryBasedLocalizationSource interface).</p>
<p>ASP.NET Boilerplate also defines some localization sources. For instance,
<strong>Abp.Web</strong> nuget package defines a localization source named "<strong>AbpWeb</strong>" 
as embedded XML files:</p>
<p>
<img alt="AbpWeb localization source files" height="147" src="/SiteFiles/Content/Documents/Resources/AbpWeb-localization-source.png" width="216" /></p>
<p>&nbsp;Default (English) XML file 
is like below (only first two texts are shown):</p>
<pre lang="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;localizationDictionary culture=&quot;en&quot;&gt;
  &lt;texts&gt;
    &lt;text name=&quot;InternalServerError&quot; value=&quot;An internal error occurred during your request!&quot; /&gt;
    &lt;text name=&quot;ValidationError&quot; value=&quot;Your request is not valid!&quot; /&gt;
    ...
  &lt;/texts&gt;
&lt;/localizationDictionary&gt;</pre>
<p>To extend AbpWeb source, we can define XML files. Assume that we only want to 
change <strong>InternalServerError</strong> text. We can define an XML file as shown below:</p>
<pre lang="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;localizationDictionary culture=&quot;en&quot;&gt;
  &lt;texts&gt;
    &lt;text name=&quot;InternalServerError&quot; value=&quot;Sorry :( It seems there is a problem. Let us to solve it and please try again later.&quot; /&gt;
  &lt;/texts&gt;
&lt;/localizationDictionary&gt;</pre>
<p>Then we can register it on PreInitialize method of our module:</p>
<pre lang="cs"><strong>Configuration.Localization.Sources.Extensions.Add</strong>(
    new LocalizationSourceExtensionInfo(&quot;<strong>AbpWeb</strong>&quot;,
        new XmlFileLocalizationDictionaryProvider(
            HttpContext.Current.Server.MapPath(&quot;<strong>~/Localization/AbpWebExtensions</strong>&quot;)
            )
        )
    );</pre>

<p>We could use XmlEmbeddedFileLocalizationDictionaryProvider if want to create 
embedded resource XML files (see Localization sources section). ASP.NET 
Boilerplate overrides (merges) base localization source with our XML files. We 
can also add new language files.</p>

<h3 id="DocConclusion">Conclusion</h3>
<p>ASP.NET Boilerplate provides ability to use different sources for 
localization. It also provides an infrastructure to use same localization texts 
both in server and client side code.</p>
<p>XML files and Resource files have own strengths and weaknesses. 
It's suggested to use XML files for re-usable modules since it will be easy to 
add new languages for module out of the code. Also, if you use XML, it's 
suggested to do not sort texts by name. Sort them by creation date. Thus, when 
someone translates it to another language, he/she can easily see which texts are 
added newly.</p>
<p>You can also create your own localization source and integrate it with 
ASP.NET Boilerplate. by implementing <strong>ILocalizationSource</strong> 
interface.</p>

</body>

</html>
